package com.dingwen.treasure.rabbitmq;

import cn.hutool.core.map.MapUtil;
import com.dingwen.treasure.base.constant.RabbitmqConstant;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Map;

/**
 * 　RabbitMQConfig: </br>
 * <p>交换机类型：</p>
 *  <ul>
 *      <li>DirectExchange： 直连交换机，通过路由key匹配队列</li>
 *      <li>FanoutExchange：扇形交换机，绑定该交换机的所有队列都会收到消息</li>
 *      <li>TopicExchange：发布订阅交换机，根据路由key的规则进行消息投递</li>
 *      <li>HeadersExchange： 根据header参数进行消息投递</li>
 *      <li>CustomExchange： 自定义交换机</li>
 *  </ul>
 * 　@author dingwen
 * 　@date 2022/6/11
 */
@SuppressWarnings("ALL")
@Configuration
public class RabbitConfig {


    /**
     * 系统操作日志交换机
     *
     * @return {@link DirectExchange}
     */
    @Bean
    public DirectExchange directExchangeOperatorLog() {
        return ExchangeBuilder.directExchange(RabbitmqConstant.DIRECT_EXCHANGE_OPERATOR_LOG)
                .durable(Boolean.TRUE)
                .autoDelete()
                .build();
    }

    /**
     * 短信直连交换机
     *
     * @return {@link DirectExchange}
     */
    @Bean
    public DirectExchange directExchangeSms() {
        // 交换机名称、持久态、关闭自动删除
        return ExchangeBuilder.directExchange(RabbitmqConstant.DIRECT_EXCHANGE_SMS)
                .durable(Boolean.TRUE)
                .autoDelete()
                .build();
    }


    /**
     * 消杀服务交换机
     *
     * @return {@link DirectExchange}
     */
    @Bean
    public DirectExchange directExchangeDisinfectServer() {
        return ExchangeBuilder.directExchange(RabbitmqConstant.DIRECT_EXCHANGE_DISINFECT_SERVER)
                .durable(Boolean.TRUE)
                .autoDelete()
                .build();
    }

    /**
     * 短信直连死信交换机
     *
     * @return {@link DirectExchange}
     */
    @Bean
    public DirectExchange directDeadExchangeSms() {
        // 交换机名称、持久态、关闭自动删除
        return ExchangeBuilder.directExchange(RabbitmqConstant.DIRECT_DEAD_EXCHANGE_SMS)
                .durable(Boolean.TRUE)
                .autoDelete()
                .build();
    }


    /**
     * 操作日志队列
     *
     * @return {@link Queue}
     */
    @Bean
    public Queue queueOperatorLog() {
        return QueueBuilder.durable(RabbitmqConstant.QUEUE_OPERATOR_LOG)
                .build();
    }


    /**
     * 消杀服务队列
     *
     * @return {@link Queue}
     */
    @Bean
    public Queue queueDisinfectServer() {
        return QueueBuilder
                .durable(RabbitmqConstant.QUEUE_DISINFECT_SERVER)
                .build();
    }

    /**
     * 短信队列
     *
     * @return {@link Queue}
     */
    @Bean
    public Queue queueSms() {
        // TTL队列
        Map<String, Object> args = MapUtil.newHashMap(3);
        // 整形 毫秒
        args.put("x-message-ttl", 5000);

        // 绑定死信交换机
        args.put("x-dead-letter-exchange", RabbitmqConstant.DIRECT_DEAD_EXCHANGE_SMS);
        args.put("x-dead-letter-routing-key", RabbitmqConstant.ROUTER_KEY_DEAD_SMS);
        return QueueBuilder.durable(RabbitmqConstant.QUEUE_SMS)
                .withArguments(args)
                .build();
    }


    /**
     * 短信死信队列 </br>
     * <p>排他队列: 只有自己可见的队列，不允许其他队列访问</p>
     * <p>特点：</p>
     * <ol>
     *     <li>只对首次声明它的连接可见</li>
     *     <li>断开连接及自动删除</li>
     * </ol>
     *
     * @return {@link Queue}
     */
    @Bean
    public Queue deadQueueSms() {
        return QueueBuilder.durable(RabbitmqConstant.DEAD_QUEUE_SMS)
                // 声明为排他队列
//                .exclusive()
                .build();
    }


    /**
     * 系统操作日志交换机和路由匹配
     *
     * @return {@link Binding}
     */
    @Bean
    public Binding bindingOperatorLog() {
        return BindingBuilder.bind(queueOperatorLog())
                .to(directExchangeOperatorLog())
                .with(RabbitmqConstant.ROUTER_KEY_OPERATOR_LOG);
    }

    /**
     * 短信死信队列交换机绑定
     *
     * @return {@link Binding}
     */
    @Bean
    public Binding deadBindingSms() {
        return BindingBuilder.bind(deadQueueSms())
                .to(directDeadExchangeSms())
                .with(RabbitmqConstant.ROUTER_KEY_DEAD_SMS);
    }

    /**
     * 短信队列交换机绑定
     *
     * @return {@link Binding}
     */
    @Bean
    public Binding bindingSms() {
        return BindingBuilder.bind(queueSms())
                .to(directExchangeSms())
                .with(RabbitmqConstant.ROUTER_KEY_SMS);
    }

    /**
     * 消杀业务绑定
     *
     * @param directExchangeDisinfectServer 消杀服务交换机
     * @param queueDisinfectServer          消杀服务队列
     * @return {@link Binding}
     */
    @Bean
    public Binding bindingDisinfectServer(DirectExchange directExchangeDisinfectServer, Queue queueDisinfectServer) {
        return BindingBuilder
                .bind(queueDisinfectServer)
                .to(directExchangeDisinfectServer)
                .with(RabbitmqConstant.ROUTER_KEY_DISINFECT_SERVER);
    }
}
